<template>
  <a-spin :loading="spinLoading" :size="35" class="w-[100%]" tip="正在处理, 请稍候...">
    <div class="file-select-container">
      <!-- 按文件来源将文件分类 -->
      <div class="file-source-sidebar">
        <a-list class="w-[240px]" hoverable size="small">
          <a-list-item
              :class="searchForm.fileSource === null ? 'file-source-active' : ''"
              class="cursor-pointer"
              @click="fileSourceClick(null)"
          >全部文件
          </a-list-item
          >
          <a-list-item
              v-for="(d, index) in dicts[proxy.DICT.fileSource]"
              :key="index"
              :class="searchForm.fileSource === d.dictKey ? 'file-source-active' : ''"
              class="cursor-pointer"
              @click="fileSourceClick(d.dictKey)"
          >
            {{ d.dictValue }}
          </a-list-item>
        </a-list>
      </div>

      <!-- 文件数据 -->
      <div class="file-content-area">
        <!-- 修改工具栏部分，移除排序选择器 -->
        <div class="file-toolbar">
          <div class="flex items-center">
            <a-upload
                :action="uploadFileUrl"
                :custom-request="customUploadFile"
                :show-file-list="false"
                multiple
                with-credentials
            >
              <a-button type="primary">
                <template #icon>
                  <icon-upload/>
                </template>
                上传文件
              </a-button>
            </a-upload>
            <a-tag v-if="isUploading" class="ml-2" color="blue">上传中...</a-tag>

            <!-- 移除视图切换按钮 -->
          </div>

          <div class="flex items-center">
            <!-- 移除排序选择器 -->
            <a-input-search
                v-model="searchForm.fileName"
                :style="{ width: '180px' }"
                placeholder="请输入文件名称"
                search-button
                @search="getPageList"
            />
          </div>
        </div>

        <!-- 文件列表 -->
        <div class="file-list-container">
          <!-- 移除网格视图，只保留列表视图 -->
          <a-table
              :data="datatable.records"
              :loading="spinLoading"
              :pagination="false"
              :row-class="getRowClass"
              :scroll="{ y: 400 }"
              @row-click="handleRowClick"
          >
            <template #columns>
              <a-table-column data-index="fileName" title="文件名">
                <template #cell="{ record }">
                  <div class="flex items-center">
                    <!-- 移除文件图标展示 -->
                    <div class="file-name-cell">
                      <!-- 添加点击文件名跳转链接 -->
                      <a
                          :href="record.fileUrl"
                          class="file-link"
                          target="_blank"
                          @click.stop
                      >
                        {{ record.fileName }}
                      </a>
                    </div>
                  </div>
                </template>
              </a-table-column>
              <!-- 其他列保持不变 -->
            </template>
          </a-table>

          <a-empty v-if="datatable.records.length === 0" class="mt-5"/>
        </div>

        <!-- 分页 -->
        <div class="pagination-container">
          <pagination
              v-if="datatable.total > 0"
              v-model:page-num="searchForm.pageNum"
              v-model:page-size="searchForm.pageSize"
              :total="datatable.total"
              @pagination="getPageList()"
          />
        </div>
      </div>
    </div>

    <!-- 分割线 -->
    <a-divider/>

    <div class="flex justify-end">
      <a-space>
        <a-button @click="cancelBtnClick()">取消</a-button>
        <a-button type="primary" @click="okBtnClick()">确定</a-button>
      </a-space>
    </div>
  </a-spin>
</template>
<script setup>
import {getCurrentInstance, onBeforeUnmount, reactive, ref, watch} from "vue";
import {getPageFileListApi, uploadFileApi} from "~/api/basic/file.js";
import {fileAccept, fileType, status} from "~/utils/sys.js";

//全局实例
const {proxy} = getCurrentInstance();
//加载字典
const dicts = proxy.LoadDicts([proxy.DICT.commonNumberStatus, proxy.DICT.fileSource]);
//允许上传的文件类型
const accept = ref("");
//接收父组件参数
const props = defineProps({
  //可以选择几个文件
  limit: {
    type: Number,
    default: () => 1,
  },
  //文件类型
  fileType: {
    type: String,
    default: () => null,
  },
});
//加载中...
const spinLoading = ref(false);
//上传中状态
const isUploading = ref(false);
//搜索参数表单
const searchForm = reactive({
  //文件来源
  fileSource: null,
  //文件类型
  fileType: null,
  //文件名称
  fileName: null,
  //文件状态 = 正常
  status: status.status_1.key,
  //页码
  pageNum: 1,
  //条数
  pageSize: 20,
});
//数据列表
const datatable = reactive({
  //数据列表
  records: [],
  //总条数
  total: 0,
});

// 时间戳，用于刷新图片缓存
const timestamp = ref(Date.now());

// 新上传的文件ID集合，用于标记需要刷新缓存的文件
const newUploadedFileIds = ref(new Set());

// 添加视图模式
// 移除视图模式相关代码
// const viewMode = ref("grid"); // 'grid' 或 'list'

// 添加排序选项
// const sortOption = ref("date-desc");
// 获取图片URL，添加时间戳防止缓存
const getImageUrl = (file) => {
  // 确保文件有URL
  if (!file.fileUrl) return "";

  const separator = file.fileUrl.includes("?") ? "&" : "?";

  // 为每个文件添加唯一的缓存参数
  // 只对新上传的文件使用全局时间戳，其他文件使用自身的更新时间
  let cacheParam = file.updateTime || file.createTime;

  // 如果是新上传的文件，使用最新的时间戳强制刷新
  if (newUploadedFileIds.value.has(file.fileId)) {
    cacheParam = timestamp.value;
  }

  return `${file.fileUrl}${separator}_id=${file.fileId}&_t=${cacheParam}`;
};

//文件来源 -> 点击
const fileSourceClick = (fileSource) => {
  //fileSource = null，查询全部
  searchForm.fileSource = fileSource;
  //查询数据列表
  getPageList();
};
//查询数据列表
// First getPageList function (original)

//选中的文件
const selectFile = ref([]);
//点击选中
const selectFileBtnClick = (file) => {
  //检查可以选择几个文件 - 默认一个
  let count = props.limit;
  //检查之前是否选中
  let selectIndex = checkSelect(file);
  //之前已选中，再次点击说明要取消掉
  if (selectIndex >= 0) {
    selectFile.value.splice(selectIndex, 1);
  } else {
    //之前未选中，检查是否达到最大个数
    if (selectFile.value.length < count) {
      //未达到最大个数，直接选择
      selectFile.value.push(file);
    } else {
      //达到最大个数，校验
      if (count === 1) {
        //最大个数=1，直接替换
        selectFile.value = [file];
      } else {
        //最大个数 > 1，提示最多可以选择 count 个
        proxy.$msg.error(`最多可以选择${count}个文件`);
      }
    }
  }
};
//检查是否选中
const checkSelect = (file) => {
  let selectIndex = -1;
  for (let i = 0; i < selectFile.value.length; i++) {
    //之前已选中
    if (selectFile.value[i].fileId === file.fileId) {
      selectIndex = i;
      break;
    }
  }
  return selectIndex;
};
//父组件函数
const emits = defineEmits(["ok", "cancel", "refresh"]);
//取消 -> 点击
const cancelBtnClick = () => {
  emits("cancel");
};
//确定 -> 点击
const okBtnClick = () => {
  emits("ok", selectFile.value);
  // 添加刷新事件，通知父组件刷新列表
  emits("refresh");
};

//上传文件地址
const uploadFileUrl = import.meta.env.VITE_UPLOAD_FILE_URL;
//自定义上传
const customUploadFile = (option) => {
  //上传进度监控
  const onUploadProgress = (e) => {
    option.onProgress(e.progress * 100);
  };

  // 设置上传中状态
  isUploading.value = true;

  // 获取原始文件
  const originalFile = option.fileItem.file;

  // 清理文件名中的特殊字符
  const sanitizedFileName = originalFile.name.replace(/[\\/:*?"<>|]/g, "_");

  // 如果需要，创建一个新的文件对象
  let fileToUpload = originalFile;
  if (sanitizedFileName !== originalFile.name) {
    fileToUpload = new File([originalFile], sanitizedFileName, {
      type: originalFile.type,
    });
  }

  //上传参数
  const formData = new FormData();
  formData.append("file", fileToUpload);
  // 使用当前选择的文件来源，如果没有选择则使用默认值
  formData.append("fileSource", searchForm.fileSource || -1);
  if (props.storageId) {
    formData.append("storageId", props.storageId);
  }

  // 添加文件类型信息
  if (props.fileType) {
    formData.append("fileType", props.fileType);
  }

  spinLoading.value = true;
  uploadFileApi(formData, onUploadProgress)
      .then((res) => {
        //调用onSuccess方法将响应数据附加到fileItem中的response字段上
        option.onSuccess(res);
        proxy.$msg.success(proxy.operationType.upload.success);

        // 更新时间戳
        timestamp.value = Date.now();

        // 记录新上传的文件ID
        if (res.fileId) {
          newUploadedFileIds.value.add(res.fileId);
        }

        // 添加短暂延迟后刷新列表，确保后端处理完成
        setTimeout(() => {
          getPageList(); // 改为 getPageList
          // 如果是单选模式，可以自动选中刚上传的文件
          if (props.limit === 1 && res.fileId) {
            selectFile.value = [res];
          }
        }, 300);
      })
      .catch((e) => {
        //上传失败
        option.onError(e);
        proxy.$msg.error("上传失败: " + (e.message || "未知错误"));
      })
      .finally(() => {
        spinLoading.value = false;
        // 重置上传中状态
        isUploading.value = false;
      });
};

//视频类型处理
const videoTypeHandler = (url) => {
  let type = url.split(".").pop().toLowerCase();
  return `video/${type}`;
};

//音频类型处理
const audioTypeHandler = (url) => {
  let type = url.split(".").pop().toLowerCase();
  return `audio/${type}`;
};

//获取文档图标
const getDocumentIcon = (fileName) => {
  const extension = fileName.split(".").pop().toLowerCase();

  // 根据文件扩展名返回对应的图标
  switch (extension) {
    case "pdf":
      return "../../../assets/file-icon/pdf.svg";
    case "doc":
    case "docx":
      return "../../../assets/file-icon/word.svg";
    case "xls":
    case "xlsx":
      return "../../../assets/file-icon/excel.svg";
    case "ppt":
    case "pptx":
      return "../../../assets/file-icon/powerpoint.svg";
    case "txt":
      return "../../../assets/file-icon/text.svg";
    case "jar":
    case "war":
    case "zip":
    case "rar":
      return "../../../assets/file-icon/archive.svg";
    default:
      return "../../../assets/file-icon/document.svg";
  }
};

// 处理排序变化
// const handleSortChange = () => {
//   const [field, order] = sortOption.value.split("-");
//
//   // 对数据进行排序
//   datatable.records.sort((a, b) => {
//     if (field === "name") {
//       return order === "asc"
//         ? a.fileName.localeCompare(b.fileName)
//         : b.fileName.localeCompare(a.fileName);
//     } else if (field === "date") {
//       const dateA = new Date(a.createTime || 0).getTime();
//       const dateB = new Date(b.createTime || 0).getTime();
//       return order === "asc" ? dateA - dateB : dateB - dateA;
//     } else if (field === "size") {
//       const sizeA = a.fileSize || 0;
//       const sizeB = b.fileSize || 0;
//       return order === "asc" ? sizeA - sizeB : sizeB - sizeA;
//     }
//     return 0;
//   });
// };

// 格式化文件大小
const formatFileSize = (size) => {
  if (!size) return "未知大小";

  const units = ["B", "KB", "MB", "GB", "TB"];
  let index = 0;
  let formattedSize = size;

  while (formattedSize >= 1024 && index < units.length - 1) {
    formattedSize /= 1024;
    index++;
  }

  return `${formattedSize.toFixed(2)} ${units[index]}`;
};

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return "";

  const date = new Date(dateString);
  const now = new Date();
  const diffMs = now - date;
  const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));

  if (diffDays === 0) {
    return (
        "今天 " + date.toLocaleTimeString("zh-CN", {hour: "2-digit", minute: "2-digit"})
    );
  } else if (diffDays === 1) {
    return (
        "昨天 " + date.toLocaleTimeString("zh-CN", {hour: "2-digit", minute: "2-digit"})
    );
  } else if (diffDays < 7) {
    // 修复这里，移除了错误的 script 关键字
    return `${diffDays}天前`;
  } else {
    return date.toLocaleDateString("zh-CN", {
      year: "numeric",
      month: "2-digit",
      day: "2-digit",
    });
  }
};

// 获取表格行的类名
const getRowClass = (record) => {
  return checkSelect(record) >= 0 ? "selected-row" : "";
};

// 处理表格行点击
const handleRowClick = (record) => {
  selectFileBtnClick(record);
};

// 获取表格中显示的文件图标
const getFileIconForTable = (file) => {
  if (!file.fileType) return "../../../assets/default-file-icon.png";

  // 如果是图片类型，直接返回默认图标
  if (file.fileType.includes("image")) {
    return "../../../assets/file-icon/image.svg";
  }

  // 对于非图片类型，根据文件后缀名判断
  if (file.fileName) {
    // 提取文件后缀
    const extension = file.fileName.split(".").pop().toLowerCase();

    // 根据文件扩展名返回对应的图标
    switch (extension) {
      case "pdf":
        return "../../../assets/file-icon/pdf.svg";
      case "doc":
      case "docx":
        return "../../../assets/file-icon/word.svg";
      case "xls":
      case "xlsx":
        return "../../../assets/file-icon/excel.svg";
      case "ppt":
      case "pptx":
        return "../../../assets/file-icon/powerpoint.svg";
      case "txt":
        return "../../../assets/file-icon/text.svg";
      case "mp4":
      case "avi":
      case "mov":
      case "flv":
      case "wmv":
      case "mkv":
        return "../../../assets/file-icon/video.svg";
      case "mp3":
      case "wav":
      case "ogg":
      case "flac":
      case "aac":
        return "../../../assets/file-icon/audio.svg";
      case "zip":
      case "rar":
      case "7z":
      case "tar":
      case "gz":
      case "jar":
      case "war":
        return "../../../assets/file-icon/archive.svg";
      default:
        return "../../../assets/file-icon/document.svg";
    }
  }

  // 如果无法通过文件名判断，则尝试通过 MIME 类型判断
  if (file.fileType.includes("video")) {
    return "../../../assets/file-icon/video.svg";
  } else if (file.fileType.includes("audio")) {
    return "../../../assets/file-icon/audio.svg";
  } else if (file.fileType.includes("pdf")) {
    return "../../../assets/file-icon/pdf.svg";
  } else if (file.fileType.includes("word") || file.fileType.includes("document")) {
    return "../../../assets/file-icon/word.svg";
  } else if (file.fileType.includes("excel")) {
    return "../../../assets/file-icon/excel.svg";
  } else if (file.fileType.includes("text")) {
    return "../../../assets/file-icon/text.svg";
  } else {
    return "../../../assets/file-icon/document.svg";
  }
};

// 获取文件类型显示文本
const getFileTypeDisplay = (file) => {
  if (!file.fileType) return "未知类型";

  if (file.fileType.includes("image")) {
    return "图片";
  } else if (file.fileType.includes("video")) {
    return "视频";
  } else if (file.fileType.includes("audio")) {
    return "音频";
  } else if (file.fileType.includes("pdf")) {
    return "PDF文档";
  } else if (file.fileType.includes("word") || file.fileType.includes("document")) {
    return "Word文档";
  } else if (file.fileType.includes("excel")) {
    return "Excel表格";
  } else if (file.fileType.includes("text")) {
    return "文本文件";
  } else {
    return file.fileType.split("/")[1] || "其他";
  }
};

// 修改查询数据列表函数，移除排序处理
const getPageList = () => {
  spinLoading.value = true;

  // 创建一个新的查询对象
  const queryParams = {...searchForm};
  // 不传递 fileType 参数给后端，让后端返回所有类型的文件
  delete queryParams.fileType;

  getPageFileListApi(queryParams)
      .then((res) => {
        // 直接使用后端返回的所有文件，不再进行筛选
        datatable.records = res.records;
        datatable.total = res.total;

        // 移除对已注释函数的调用
        // handleSortChange();

        // 列表刷新后，清理新上传文件ID集合
        setTimeout(() => {
          newUploadedFileIds.value.clear();
        }, 1000); // 给予一定延迟，确保图片加载完成
      })
      .finally(() => {
        spinLoading.value = false;
        // 重置上传中状态
        isUploading.value = false;
      });
};

//监听参数变化
watch(
    () => props.fileType,
    (newVal, oldVal) => {
      //文件类型
      if (props.fileType) {
        searchForm.fileType = props.fileType;
      }
      //允许上传的文件类型
      //图片文件
      if (props.fileType === fileType.image.key) {
        accept.value = fileAccept.img;
      }
      //视频文件
      else if (props.fileType === fileType.video.key) {
        accept.value = fileAccept.video;
      }
      //音频文件
      else if (props.fileType === fileType.audio.key) {
        accept.value = fileAccept.audio;
      }
      //文档文件
      else if (props.fileType === fileType.document.key) {
        accept.value = fileAccept.document;
      }
      //所有文件
      else {
        accept.value = fileAccept.all;
      }
      //加载文件列表
      getPageList(); // 改为 getPageList
    },
    {deep: true, immediate: true}
);
// 组件卸载前清理资源
onBeforeUnmount(() => {
  newUploadedFileIds.value.clear();
});
</script>
<style scoped>
/* 文件选择器整体布局 */
.file-select-container {
  display: flex;
  height: 600px; /* 固定高度 */
  width: 100%;
  background-color: var(--color-bg-2);
  border-radius: 8px;
  overflow: hidden;
}

/* 左侧文件来源侧边栏 */
.file-source-sidebar {
  width: 240px;
  border-right: 1px solid var(--color-border);
  padding-right: 12px;
  height: 100%;
  overflow-y: auto;
  background-color: var(--color-bg-1);
}

/* 文件来源激活状态 */
.file-source-active {
  background-color: var(--color-fill-2) !important;
  color: var(--color-primary) !important;
  font-weight: 500;
}

/* 右侧内容区域 */
.file-content-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 0 16px;
  height: 100%;
  overflow: hidden;
}

/* 工具栏 */
.file-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-border-2);
}

/* 文件列表容器 */
.file-list-container {
  flex: 1;
  overflow-y: auto;
  padding: 16px 0;
  height: calc(100% - 100px); /* 减去工具栏和分页的高度 */
}

/* 网格视图 - 4行8列布局 */
.file-grid-view {
  display: grid;
  grid-template-columns: repeat(8, 1fr); /* 8列 */
  grid-template-rows: repeat(4, 150px); /* 4行，每行150px高度 */
  gap: 16px;
  padding: 8px 0;
  width: 100%;
  min-width: 1200px; /* 确保最小宽度能容纳8列 */
  overflow-y: auto; /* 超出部分可滚动 */
}

/* 文件网格项 */
.file-grid-item {
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
  background-color: #fff;
  cursor: pointer;
  user-select: none;
  height: 150px; /* 固定高度适应4行布局 */
  width: 100%;
  min-width: 130px;
  max-width: 180px;
  border: 2px solid transparent;
}

/* 选中状态 */
.file-selected {
  border-color: var(--color-primary);
  background-color: var(--color-fill-2);
}

/* 文件预览区域 */
.file-preview {
  position: relative;
  width: 100%;
  height: 90px; /* 调整高度 */
  overflow: hidden;
  background-color: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: center;
}

.file-preview img,
.file-preview video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 文件名称 */
.file-name {
  padding: 8px 12px 4px;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 文件元数据 */
.file-meta {
  padding: 0 12px 8px;
  font-size: 12px;
  color: var(--color-text-3);
}

/* 分页容器 */
.pagination-container {
  display: flex;
  justify-content: flex-end;
  padding: 12px 0;
  border-top: 1px solid var(--color-border-2);
}

/* 文档和其他文件包装器 */
.document-wrapper,
.other-file-wrapper,
.audio-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f9f9f9;
}

/* 表格视图样式 */
:deep(.arco-table-tr) {
  cursor: pointer;
}

:deep(.arco-table-td) {
  padding: 8px 16px;
}

.file-name-cell {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 300px;
}

/* 选中行样式 */
:deep(.selected-row) {
  background-color: var(--color-fill-2);
}

/* 文件链接样式 - 美化版 */
.file-link {
  color: var(--color-text-1);
  text-decoration: none;
  transition: all 0.3s ease;
  position: relative;
  padding: 2px 4px;
  border-radius: 4px;
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-link:hover {
  color: var(--color-primary);
  background-color: var(--color-fill-1);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.file-link:active {
  transform: translateY(1px);
}

/* 为不同类型的文件添加不同的前缀图标 */
.file-link::before {
  content: "📄 ";
  margin-right: 4px;
  font-size: 14px;
}

/* 为图片文件添加特殊图标 */
.file-link[href$=".jpg"]::before,
.file-link[href$=".jpeg"]::before,
.file-link[href$=".png"]::before,
.file-link[href$=".gif"]::before,
.file-link[href$=".webp"]::before {
  content: "🖼️ ";
}

/* 为视频文件添加特殊图标 */
.file-link[href$=".mp4"]::before,
.file-link[href$=".avi"]::before,
.file-link[href$=".mov"]::before {
  content: "🎬 ";
}

/* 为音频文件添加特殊图标 */
.file-link[href$=".mp3"]::before,
.file-link[href$=".wav"]::before,
.file-link[href$=".ogg"]::before {
  content: "🎵 ";
}

/* 为文档文件添加特殊图标 */
.file-link[href$=".pdf"]::before {
  content: "📕 ";
}

.file-link[href$=".doc"]::before,
.file-link[href$=".docx"]::before {
  content: "📝 ";
}

.file-link[href$=".xls"]::before,
.file-link[href$=".xlsx"]::before {
  content: "📊 ";
}

.file-link[href$=".ppt"]::before,
.file-link[href$=".pptx"]::before {
  content: "📑 ";
}

/* 为压缩文件添加特殊图标 */
.file-link[href$=".zip"]::before,
.file-link[href$=".rar"]::before,
.file-link[href$=".7z"]::before {
  content: "🗜️ ";
}
</style>
